package main

import "fmt"

func main() {
	// Go语言的 defer 语句会将其后面跟随的语句进行延迟处理，
	// 在 defer 归属的函数即将返回时，将延迟处理的语句按 defer 的逆序进行执行，
	// 也就是说，先被 defer 的语句最后被执行，最后被 defer 的语句，最先被执行。
	// 关键字 defer 的用法类似于面向对象编程语言 Java 和 C# 的 finally 语句块，
	// 它一般用于释放某些已分配的资源，典型的例子就是对一个互斥解锁，或者关闭一个文件。
	fmt.Println("defer begin")

	// 将defer放入延迟调用栈
	defer fmt.Println(1)

	defer fmt.Println(2)

	// 最后一个放入, 位于栈顶, 最先调用
	defer fmt.Println(3)

	// defer 只收“调用表达式”；想延迟多条，包匿名函数立即执行。
	defer func() {
		fmt.Println("defer in func")
	}()

	fmt.Println("defer end")
}

// defer 绝不引入并发或乱序，它只是把你写的代码“压进一条 LIFO 栈”，仍在当前 goroutine、仍在当前线程、仍按你写的同步顺序执行，
// 只是时间点后移到函数 return 前

// 实现原理： 运行时栈 + 编译期插桩 两套机制；
// 它的设计目标也远不止“语法糖”，而是让 资源释放（unlock/close） 与 获取（lock/open） 能视觉上紧邻、执行上逆序、逻辑上绝不漏掉
